/*
**********************************************************************************
    OpenSURF642 : An TI DM642 implementation of OpenSURF.
    Copyright (C) 2011  Hai Yu

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
	This implementation is based on The original OpenSURF library created
	by Christopher Evans.The original work can be found at
		http://www.chrisevansdev.com/computer-vision-opensurf.html
	
    contact: yuhaihai12345@gmail.com	
**********************************************************************************
*/

#ifndef _FAST_HESSIAN_
#define _FAST_HESSIAN_
#include "OpenSurf642Util.h"
#include "ResponseLayer.h"
#include "IPoint.h"
#include "matrix.h"

/***********    Definition of constants  ***************************/
#define OCTAVES 5
#define INTERVALS  4
#define THRES  0.0004f
#define INIT_SAMPLE 2

#define MAX_IPTS 2048
#define MAX_RESPONSELAYER 12


/***********    Definition of structures  ***************************/
typedef struct
{
	IntegralImage *image;

	Uint16 i_width, i_height;

	IPoint *ipts;
	Uint16 ipts_count;
	ResponseLayer * responseMap[MAX_RESPONSELAYER];
	Uint16 responseMap_count;

	Uint16 octaves;
	Uint16 intervals;
	Uint16 init_samples;
	ResponseDataType thres;
}FastHessians;


/***********    Declaration of Interfaces  ***************************/

/*
*******************************************************************
*	Build a FastHessians object		
*	Params:		IntegralImage * image	 Input Integral Image
*				Uint16     Octaves       Number of octaves
*				Uint16     Intervals     Number of intervals in pixels
*				Uint16     init_samples   Initial sampling rate
*				ResponseDataType  thres   Threshold for ignoring hessian
*										  responses
*	Return: An properly initialized FastHessians object 
**********************************************************************
*/
FastHessians * CreateFastHessians(	IntegralImage * image, 
									Uint16 Octaves,
									Uint16 Intervals,
									Uint16 init_samples, 
									ResponseDataType thres);

//	Release a FastHessians Object		
void DestroyFastHessians(FastHessians * self);

//	Set parameters of a FastHessians object		
void SetParameter(	FastHessians * self, 
					Uint16 octaves, 
					Uint16 intervals, 
					Uint16 init_samples, 
					ResponseDataType thres);

/*
*******************************************************************
*	Detect all interesting points 		
*	Params:		FastHessians * self	     FastHessians Object to release
*   Note:       All parameters and integral images must
*				be properly set before calling this function
**********************************************************************
*/
void DetectIPoints( FastHessians * self);


/*
*******************************************************************
*	Set a new integral image for a FastHessians object 		
*	Params:		FastHessians * self	     FastHessians Object
*				IntegralImage * image    new integral image
**********************************************************************
*/
void SetImage(FastHessians * self, IntegralImage * image);



/***********    Declaration of Internal Functions  *******************/

// Calculate all response layers of a FastHessians Object
void buildResponseMap(FastHessians * self);

//Calculate a single layer of a FastHessians Object
void buildResponseLayer(FastHessians * self, ResponseLayer * rl); 

/*
*******************************************************************
*	Interpolate scale-space extrema to subpixel accuracy to form an image feature.		
*	Params:		FastHessians * self	     FastHessians Object
*				IntegralImage * image    new integral image
*				Uint16   r               row of IPoint in middle layer
*				Uint16   c               column of IPoint in middle layer
*				ResponseLayer * t        top layer
*				ResponseLayer * m        middle layer
*				ResponseLayer * b        bottom layer
**********************************************************************
*/
void interpolateExtremum(	FastHessians * self, 
							Uint16 r,
							Uint16 c,
							ResponseLayer * t,
							ResponseLayer * m,
							ResponseLayer * b);

/*
*******************************************************************
*	Find the 3D coordinate of scale-space extrema		
*	Params:		FastHessians * self	     FastHessians Object
*				IntegralImage * image    new integral image
*				Uint16   r               row of IPoint in middle layer
*				Uint16   c               column of IPoint in middle layer
*				ResponseLayer * t        top layer
*				ResponseLayer * m        middle layer
*				ResponseLayer * b        bottom layer
*               float *xi, *xr, *xc      scale space coordinate
**********************************************************************
*/
void interpolateStep(	FastHessians * self,
						Uint16 r,
						Uint16 c,
						ResponseLayer * t,
						ResponseLayer * m,
						ResponseLayer * b,
						float * xi,
						float * xr,
						float * xc);

/*
*******************************************************************
*	9 * 9 nonmax supression		
*	Params:		Uint16   r               row of IPoint in middle layer
*				Uint16   c               column of IPoint in middle layer
*				ResponseLayer * t        top layer
*				ResponseLayer * m        middle layer
*				ResponseLayer * b        bottom layer
*               float *xi, *xr, *xc      scale space coordinate
*	Return:   0 if not extremum, 1 for extremum
**********************************************************************
*/
Uint8 isExtremum(	FastHessians * self,
					Uint16 r,
					Uint16 c,
					ResponseLayer * t,
					ResponseLayer * m,
					ResponseLayer * b);


/*
*******************************************************************
*	Calculate 3D hessian matrix	
*	Params:		Uint16   r               row of IPoint in middle layer
*				Uint16   c               column of IPoint in middle layer
*				ResponseLayer * t        top layer
*				ResponseLayer * m        middle layer
*				ResponseLayer * b        bottom layer
*               float *xi, *xr, *xc      scale space coordinate
*	Return:   3 * 3 Hessian matrix
**********************************************************************
*/
Matrix * hessian3D(	Uint16 r,
					Uint16 c,
					ResponseLayer * t,
					ResponseLayer * m,
					ResponseLayer * b);

					/*
*******************************************************************
*	Calculate 3D derivative
*	Params:		Uint16   r               row of IPoint in middle layer
*				Uint16   c               column of IPoint in middle layer
*				ResponseLayer * t        top layer
*				ResponseLayer * m        middle layer
*				ResponseLayer * b        bottom layer
*               float *xi, *xr, *xc      scale space coordinate
*	Return:   3 * 1 derivative
**********************************************************************
*/
Matrix * deriv3D(	Uint16 r,
					Uint16 c,
					ResponseLayer * t,
					ResponseLayer * m,
					ResponseLayer * b);

#endif

